<template>
  <div class="sc-upload-file">
    <el-upload
      :disabled="disabled"
      :auto-upload="autoUpload"
      :action="action"
      :name="name"
      :data="data"
      :http-request="request"
      v-model:file-list="defaultFileList"
      :show-file-list="showFileList"
      :drag="drag"
      :accept="accept"
      :multiple="multiple"
      :limit="limit"
      :before-upload="before"
      :on-success="success"
      :on-error="error"
      :on-preview="handlePreview"
      :on-exceed="handleExceed"
    >
      <slot>
        <el-button type="primary" :disabled="disabled"
          >Click to upload</el-button
        >
      </slot>
      <template #file="{ file }">
        <div
          class="imageList"
          @mouseenter="handleMouseEnter(file)"
          @mouseleave="handleMouseLeave"
          v-if="isImage(file.name)"
        >
          <div
            :class="
              currentfile.name == file.name && currentfile.uid == file.uid
                ? 'shade'
                : ''
            "
          ></div>
          <img class="image-thumbnail" :src="file.url" alt="" />
          <!-- <img
            class="image-thumbnail"
            src="http://rwblnjq08.hn-bkt.clouddn.com/805b8289b0724b368ed7905a8382e1bc.jpg"
            alt=""
          /> -->
          <span
            class="image-actions"
            :class="
              currentfile.name == file.name && currentfile.uid == file.uid
                ? 'showIcon'
                : ''
            "
          >
            <span class="image-preview" @click="handlePreview(file)">
              <el-icon><el-icon-zoom-in /></el-icon>
            </span>
            <span
              v-if="!disabled"
              class="image-delete"
              @click="handleRemove(file)"
            >
              <el-icon><el-icon-delete /></el-icon>
            </span>
          </span>
        </div>
        <div
          class="documentList"
          @mouseenter="handleMouseEnter(file)"
          @mouseleave="handleMouseLeave"
          v-else
        >
          <div class="name" @click="downloadFile(file)">{{ file.name }}</div>
          <span
            class="image-actions"
            :class="
              currentfile.name == file.name && currentfile.uid == file.uid
                ? 'showIcon'
                : ''
            "
          >
            <span
              v-if="!disabled"
              class="image-delete"
              @click="handleRemove(file)"
            >
              <el-icon><el-icon-delete /></el-icon>
            </span>
          </span>
        </div>
      </template>
    </el-upload>

    <el-dialog v-model="dialogVisible" width="70%">
      <!-- <img w-full :src="dialogImageUrl" alt="Preview Image" class="image" /> -->
      <el-image :src="dialogImageUrl" fit="cover"></el-image>
    </el-dialog>

    <span style="display: none !important"
      ><el-input v-model="value"></el-input
    ></span>
  </div>
</template>

<script>
import config from "@/config/upload"

export default {
  props: {
    modelValue: { type: [String, Array], default: "" },
    tip: { type: String, default: "" },
    action: { type: String, default: "" },
    apiObj: { type: Object, default: () => { } },
    name: { type: String, default: config.filename },
    data: { type: Object, default: () => { } },
    accept: { type: String, default: "" },
    maxSize: { type: Number, default: config.maxSizeFile },
    limit: { type: Number, default: 0 },
    autoUpload: { type: Boolean, default: true },
    showFileList: { type: Boolean, default: true },
    drag: { type: Boolean, default: false },
    multiple: { type: Boolean, default: true },
    disabled: { type: Boolean, default: false },
    onSuccess: { type: Function, default: () => { return true } }
  },
  data () {
    return {
      value: "",
      defaultFileList: [],
      dialogImageUrl: '',
      dialogVisible: false,
      currentfile: '',
      imageList: [],
      documentList: []
    }
  },
  watch: {
    modelValue (val) {
      if (Array.isArray(val)) {
        if (JSON.stringify(val) != JSON.stringify(this.formatArr(this.defaultFileList))) {
          this.defaultFileList = val
          this.value = val
        }
      } else {
        if (val != this.toStr(this.defaultFileList)) {
          this.defaultFileList = this.toArr(val)
          this.value = val
        }
      }
    },
    defaultFileList: {
      handler (val) {
        this.$emit('update:modelValue', Array.isArray(this.modelValue) ? this.formatArr(val) : this.toStr(val))
        this.value = this.toStr(val)
      },
      deep: true
    }
  },
  mounted () {
    this.defaultFileList = Array.isArray(this.modelValue) ? this.modelValue : this.toArr(this.modelValue)
    this.value = this.modelValue
  },
  methods: {
    handleMouseEnter (file) {
      this.currentfile = file
    },
    handleMouseLeave () {
      this.currentfile = ''
    },
    // 判断是否是图片
    isImage (file) {
      if (file) {
        let arr = file.split('.')
        let type = arr[arr.length - 1]
        let imageType = 'jpg/png/jpeg/svg'
        if (imageType.includes(type)) {
          return true
        } else {
          return false
        }
      }

    },
    //默认值转换为数组
    toArr (str) {
      var _arr = []
      var arr = str.split(",")
      arr.forEach(item => {
        if (item) {
          var urlArr = item.split('/')
          var fileName = urlArr[urlArr.length - 1]
          _arr.push({
            name: fileName,
            url: item
          })
        }
      })
      return _arr
    },
    //数组转换为原始值
    toStr (arr) {
      return arr.map(v => v.url).join(",")
    },
    //格式化数组值
    formatArr (arr) {
      var _arr = []
      arr.forEach(item => {
        if (item) {
          _arr.push({
            name: item.name,
            url: item.url
          })
        }
      })
      return _arr
    },
    before (file) {
      const maxSize = file.size / 1024 / 1024 < this.maxSize
      if (!maxSize) {
        this.$message.warning(`上传文件大小不能超过 ${this.maxSize}MB!`)
        return false
      }
    },
    success (res, file) {
      let imageList = []
      let documentList = []
      this.defaultFileList.forEach(item => {
        if (this.isImage(item.name)) {
          imageList.push(item)
        } else {
          documentList.push(item)
        }
      })

      // this.defaultFileList = [this.imageList, this.documentList]
      this.defaultFileList = imageList.concat(documentList)
      // this.defaultFileList.push(list)
      console.log(this.defaultFileList)

      var os = this.onSuccess(res, file)
      if (os != undefined && os == false) {
        return false
      }
      // var response = config.parseData(res)
      file.name = res.data.fileName
      file.url = res.data.filePath
      if (res.code == 200) {
        this.$notify.success({
          title: '成功',
          message: '文件上传成功',
        })
      }
    },
    error (err) {
      this.$notify.error({
        title: '上传文件未成功',
        message: err
      })
    },
    beforeRemove (uploadFile) {
      return this.$confirm(`是否移除 ${uploadFile.name} ?`, '提示', {
        type: 'warning',
      }).then(() => {
        return true
      }).catch(() => {
        return false
      })
    },
    handleExceed () {
      this.$message.warning(`当前设置最多上传 ${this.limit} 个文件，请移除后上传!`)
    },
    handlePreview (uploadFile) {
      // window.open(uploadFile.url)
      this.dialogImageUrl = uploadFile.url
      this.dialogVisible = true
    },
    handleRemove (file) {
      console.log('删除')
      this.defaultFileList.forEach((item, index) => {
        if (item.name == file.name && item.uid == file.uid) {
          this.defaultFileList.splice(index, 1)
        }
      })
      this.imageList.forEach((item, index) => {
        if (item.name == file.name && item.uid == file.uid) {
          this.imageList.splice(index, 1)
        }
      })
      this.documentList.forEach((item, index) => {
        if (item.name == file.name && item.uid == file.uid) {
          this.documentList.splice(index, 1)
        }
      })
    },
    request (param) {
      var apiObj = config.apiObjFile
      if (this.apiObj) {
        apiObj = this.apiObj
      }
      const data = new FormData()
      data.append(param.filename, param.file)
      for (const key in param.data) {
        data.append(key, param.data[key])
      }
      apiObj.post(data, {
        onUploadProgress: e => {
          const complete = parseInt(((e.loaded / e.total) * 100) | 0, 10)
          param.onProgress({ percent: complete })
        }
      }).then(res => {
        var response = config.parseData(res)
        if (response.code == config.successCode) {
          param.onSuccess(res)
        } else {
          param.onError(response.msg || "未知错误")
        }
      }).catch(err => {
        param.onError(err)
      })
    },
    // 下载文件
    downloadFile (file) {
      const a = document.createElement('a')
      a.target = "_blank"
      a.href = file.url
      a.download = file.name // 下载文件的名称
      a.style.display = 'none'
      // 隐藏a标签
      document.body.appendChild(a)       // 将a标签追加到文档对象中
      a.click()                          // 模拟点击了a标签，会触发a标签的href的读取，浏览器就会自动下载了
      a.remove()                        // 一次性的，用完就删除a标签

    }
  }
}
</script>

<style  lang='scss' scoped>
.imageList {
  position: relative;
  width: 110px;
  height: 110px;
  margin-right: 10px;
  .image-thumbnail {
    width: 110px;
    height: 110px;
    object-fit: cover;
  }
  .image-actions {
    display: none;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    .el-icon {
      font-size: 20px;
      color: #fff;
    }
  }
  .showIcon {
    display: block;
  }
  .image-preview {
    margin-right: 5px;
  }
  .shade {
    position: absolute;
    top: 0;
    left: 0;
    width: 110px;
    height: 110px;
    background: #33333363;
  }
}

.documentList {
  display: flex;
  justify-content: space-between;
  align-items: center;
  .name {
    margin-right: 30px;
    &:hover {
      text-decoration: underline;
      cursor: pointer;
    }
  }
  .image-actions {
    display: none;
  }
  .el-icon {
    // margin-top: 12px;
    vertical-align: middle;
  }
  .showIcon {
    display: block;
  }
}
.el-upload-list__item:hover {
  background-color: transparent;
}
.el-upload-list {
  // display: flex;
}
</style>
